package work.month06.day28;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * @date 2020/06/28
 * @author 王光浩
 * @introduction 创建一个文件切割器，用于切割文件
 */
public class FileSplitter {

	private final int size; // 将文件切割之后每一个小文件的最大size

	/**
	 * 将构造器私有化，使用静态方法获取实例
	 */
	private FileSplitter(int size) {
		this.size = size;
	}

	/**
	 * 静态工厂方法，用于获取一个FileSplitter实例。
	 * @param size 将文件切割之后每一个小文件的最大size
	 * @return 返回一个 FileSplitter 对象
	 */
	public static FileSplitter getInstance(int size) {
		return new FileSplitter(size);
	}

	/**
	 * 将 origin 所表示的文件进行切割，每一个小文件的最大 size 是以前的
	 * @param origin
	 * @param destination
	 * @return 返回最终文件被切割的份数
	 */
	public int split(File origin, File destination) {
		// 对参数进行检测
		if (origin == null || !origin.exists() || !origin.isFile())
			throw new IllegalArgumentException("被拆分的文件不存在");
		if (destination == null || !destination.exists() || !destination.isDirectory())
			throw new IllegalArgumentException("目标位置不存在或不有效目录");

		// 声明相关变量
		byte[] buffer = new byte[size];
		InputStream in = null;
		OutputStream out = null;
		File temp = null;
		int len = 0;
		int index = 1;

		// 将文件进行拆分
		try {
			in = new FileInputStream(origin);

			// 1. 获取文件的后缀名以及文件名
			String postfix = origin.getCanonicalPath().substring(origin.getCanonicalPath().lastIndexOf("."));
			String name = origin.getName().substring(0, origin.getName().indexOf("."));

			// 2. 将 file 中的内容按照 size大小 依次读取出
			while ((len = in.read(buffer)) != -1) {

				// 3. 在对应 path 目录下创建一个新的文件
				temp = new File(destination.getCanonicalPath() + "/" + name + "_" + (index++) + "_" + postfix);
				if (!temp.exists())
					temp.createNewFile();

				// 4. 将数据写入到对应的文件中
				try {
					out = new FileOutputStream(temp);
					out.write(buffer, 0, len);
				} catch (IOException e) {
					System.out.println("文件写入异常");
				} finally {
					out.close();
				}
			}
		} catch (IOException e) {
			System.out.println("文件读出异常");
		} finally {
			// 5. 关闭输入流
			if (in != null)
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
		
		return --index;
	}
	
	
}
